package com.oneandone.httpserver.tcp.http;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.log4j.Logger;

import com.oneandone.httpserver.tcp.ProtocolHandler;
import com.oneandone.httpserver.tcp.http.request.BadRequestException;
import com.oneandone.httpserver.tcp.http.request.BasicHttpRequestParser;
import com.oneandone.httpserver.tcp.http.request.HttpRequest;
import com.oneandone.httpserver.tcp.http.response.BasicHttpResponseSerializer;
import com.oneandone.httpserver.tcp.http.response.HttpResponse;
import com.oneandone.httpserver.tcp.http.response.HttpStatus;
import com.oneandone.httpserver.tcp.http.route.BasicHttpRouter;
import com.oneandone.httpserver.tcp.http.route.RequestHandler;
import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;

/**
 * Basic implementation of HTTP/1.1 protocol. Still needs improvement
 * <br/>
 * TODO: at least try to comply with:
 * <a href="http://www.jmarshall.com/easy/http/#http1.1servers">HTTP 1.1 Servers</a>
 *
 * @author calin
 */
public class BasicHttpHandler implements ProtocolHandler {
	private static final Logger LOGGER = Logger.getLogger(BasicHttpHandler.class);
	private BasicHttpRouter httpRouter;
	private BasicHttpResponseSerializer httpRespSerial;
	private BasicHttpRequestParser httpReqParser;
	
	public BasicHttpHandler(BasicHttpRouter httpRouter, BasicHttpResponseSerializer httpRespSerial,
			BasicHttpRequestParser httpReqParser){
		this.httpRouter = httpRouter;
		this.httpRespSerial = httpRespSerial;
		this.httpReqParser = httpReqParser;
	}
	
    @Override
    public boolean handle(InputStream inputStream, OutputStream outputStream) throws IOException {
        try {
			HttpRequest httpReq = httpReqParser.parse(inputStream);
			RequestHandler httpHandler = httpRouter.findRoute(httpReq.getMethod(), httpReq.getUrl());
			HttpResponse httpResp = httpHandler.handle(httpReq);
			httpRespSerial.serialize(httpResp, outputStream);
			outputStream.close();
        } catch (BadRequestException e) {
			LOGGER.debug("BadRequestExcepetion at HTTP handler");
			LOGGER.debug("Generating Bad Request Response");
        	httpRespSerial.serialize(generateBadReqMessage(), outputStream);
		}
        
    	return false;  //To change body of implemented methods use File | Settings | File Templates.
    }
    
    public HttpResponse generateBadReqMessage(){
    	HttpResponse httpResp = HttpResponse.status(HttpStatus.BAD_REQUEST);
    	httpResp.header("Content-Type", "text/html");
    	httpResp.header("Content-Length", 111);
    	String body = "<html><body>\r\n" +
    			"<h2>No Host: header received</h2>\r\n" +
    			"HTTP 1.1 requests must include the Host: header.\r\n" +
    			"</body></html>"; 
    	httpResp.body(new ByteArrayInputStream(body.getBytes()));
    	
    	return httpResp;
    	
    }
}
